﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CLVisionModbusTS
{
    internal class ModbusOptions
    {
        private Dictionary<int, ConfigurationItem> dicModubus = new Dictionary<int, ConfigurationItem>();

        public Dictionary<int, ConfigurationItem> DicModubus { get => dicModubus; set => dicModubus = value; }


        public void  LoadConfig()
        {
         
            Customer customer = null;

            var data_default = Properties.Resource1._default;
            string defaultJson = Encoding.UTF8.GetString(data_default);
            customer = JSONToEntity<Customer>(defaultJson);
            RestoreFromJsonString(customer);



            var data_cus = Properties.Resource1.Customer;
            string customerJson = Encoding.UTF8.GetString(data_cus);
            customer = JSONToEntity<Customer>(customerJson);
            RestoreFromJsonString(customer);

            var data_cus_TS = Properties.Resource1.Customer_TS;
            string customerJson_TS = Encoding.UTF8.GetString(data_cus_TS);
            customer = JSONToEntity<Customer>(customerJson_TS);
            RestoreFromJsonString(customer);



        }
        private  void RestoreFromJsonString(Customer customer)
        {
            SetData( customer.Input, true);
            SetData(customer.Output, false);
        }
        private  void SetData( List<CustomerObject> customerObjects, bool isInput)
        {
            for (int i = 0; i < customerObjects.Count; i++)
            {
                //起始地址
                int startIndex = customerObjects[i].ModbusStartAddress;
                for (int j = 0; j < customerObjects[i].items.Count; j++)
                {
                    ConfigurationItem pinConfigurationItem = new ConfigurationItem();
                    pinConfigurationItem.DataType = TransTypeInfo( customerObjects[i].items[j].DataType);
                    string name = customerObjects[i].items[j].Name;
                    pinConfigurationItem.ModbusAddress = startIndex;
                    pinConfigurationItem.Name = customerObjects[i].items[j].Name;
                    //下一次起始地址
                    startIndex += TransModbusAddressLenth(customerObjects[i].items[j].DataType);
                    pinConfigurationItem.ModubusType = TransModbusType(isInput, customerObjects[i].items[j].DataType);
                    pinConfigurationItem.ObjectID = customerObjects[i].items[j].ObjectID;
                    dicModubus.Add(pinConfigurationItem.ObjectID, pinConfigurationItem);

                }

            }
        }
        private static int TransModbusAddressLenth(string DataType)
        {
            int info = 0;
            switch (DataType)
            {
                case "Boolean":
                    info = 1;
                    break;
                case "Integer":
                    info = 2;
                    break;
                case "Floating point number":
                    info = 4;
                    break;
                //case "String":
                //   info = 44; 
                //   break;
                case "String":
                    info = 40;
                    break;
                case "(Process)Free Signal":
                    info = 1;
                    break;
                case "(Process)Signal":
                    info = 1;
                    break;
                case "(Process)Identifier":
                    info = 2;
                    break;
            }
            return info;
        }
        private static string TransTypeInfo(string DataType)
        {
           string info = default;
            switch (DataType)
            {
                case "Boolean":
                    info = "Boolean";
                    break;
                case "Integer":
                    info = "Integer";
                    break;
                case "Floating point number":
                    info = "Double";
                    break;
                case "String":
                    info = "String";
                    break;
                case "(Process)Free Signal":
                    info = "Boolean";
                    break;
                case "(Process)Signal":
                    info = "Boolean";
                    break;
                case "(Process)Identifier":
                    info = "Integer";
                    break;
            }
            return info;
        }
        private static string TransModbusType(bool isInput, string DataType)
        {
            string info = "";
            switch (DataType)
            {
                case "Boolean":
                    info = isInput ? "Coil" : "Discrete Input";
                    break;
                case "Integer":
                    info = isInput ? "Holding Register" : "Input Register";
                    break;
                case "Floating point number":
                    info = isInput ? "Holding Register" : "Input Register";
                    break;
                case "String":
                    info = isInput ? "Holding Register" : "Input Register";
                    break;
                case "(Process)Free Signal":
                    info = isInput ? "Coil" : "Discrete Input";
                    break;
                case "(Process)Signal":
                    info = isInput ? "Coil" : "Discrete Input";
                    break;
                case "(Process)Identifier":
                    info = isInput ? "Holding Register" : "Input Register";
                    break;
            }

            return info;
        }
        private static T JSONToEntity<T>(string jsonStr) where T : class
        {
            T t = default(T);
            try
            {
                t = (T)JsonConvert.DeserializeObject(jsonStr, typeof(T));
            }
            catch (Exception)
            {

                t = default(T);
            }
            return t;
        }
    }

    internal class ConfigurationItem
    {
        private string _name;
        private string _dataType;
        private string _modubusType;
        private int _modbusAddress;
        private int _objectID;

        public string Name { get => _name; set => _name = value; }
        public string DataType { get => _dataType; set => _dataType = value; }
        public string ModubusType { get => _modubusType; set => _modubusType = value; }
        public int ModbusAddress { get => _modbusAddress; set => _modbusAddress = value; }
        public int ObjectID { get => _objectID; set => _objectID = value; }
    }

}
